package room

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"github.com/topfreegames/pitaya"
	"github.com/topfreegames/pitaya/constants"
	"pitaya_new_chatroom/protos"
	"pitaya_new_chatroom/utils"
	"sync"
)

/**
 	功能需求

		创建新房间 √
		玩家进房间 √
		说话√
		退出房间√
		前端断线的情况 ，这里demo逻辑就是把该用户提出房间

 */

type Room struct{
	RoomName string
	ID  string
	Master string
	member map[string]*UserInfo
	RW sync.RWMutex  `json:"-"`
}

// userInfo

type UserInfo struct {
	Username string
}


// 创建一个新房间
func NewRoom() *Room {
	roomId:= uuid.New()
	return &Room{
		ID:roomId.String(),
		RoomName:"新群聊",
		Master:"",
		member:make(map[string]*UserInfo),
	}
}
//todo 只有房主才能解散清理房间
func (r *Room)CleanRoom(ctx context.Context,data *protos.CleanRoomReq)(*protos.RequestRes,error){
	s := pitaya.GetSessionFromCtx(ctx)
	uid:= s.UID()
	r.RW.Lock()
	defer r.RW.Unlock()
	_,ok := r.member[uid]
	if uid == "" || !ok{

		return utils.Utils.ReturnTextData("leaveRoomRespond", "10003",ctx),nil
	}

	for curId,_:=range r.member{
		r.ClearUserInfo(curId)
	}

	return utils.Utils.ReturnCustomTextData("leaveRoomRespond", 200,"清理完成",ctx),nil
}

func (r *Room)LeaveRoom(ctx context.Context)(*protos.RequestRes,error){
	s := pitaya.GetSessionFromCtx(ctx)
	uid:= s.UID()
	r.RW.Lock()
	defer r.RW.Unlock()

	userInfo ,ok := r.member[uid]
	if uid == "" || !ok{
		return utils.Utils.ReturnCustomTextData("leaveRoomRespond", 200,"用户不在房间",ctx),nil
	}
	pitaya.GroupBroadcast(
		ctx,
		"chatroom",
		r.ID,
		"onLeaveUser",
		utils.Utils.ReturnCustomTextData("leaveRoomNotify",200,	fmt.Sprintf("用户[%s]离开房间",userInfo.Username),ctx ),
	)

	// 打印一下 房间人数
	count, _ := pitaya.GroupCountMembers(context.Background(), r.ID)
	fmt.Printf("当前房间人数：%d",count)


	//把用户信息从该房间清理掉,并通知房间呢的所有成员
	_,err:= r.ClearUserInfo(uid)

	if err != nil{
		return 	utils.Utils.ReturnTextData("messageRespond", "10004",ctx),nil
	}


	return 	utils.Utils.ReturnCustomTextData("leaveRoomRespond", 200,"离开房间成功",ctx),nil
}

func (r *Room) ClearUserInfo(uid string) (*UserInfo, error){
	userInfo ,ok := r.member[uid]
	if !ok  {
		return nil,errors.New("用户不在房间")
	}
	delete(r.member,uid )
	memberLen:=len(r.member)

	fmt.Println("房间人数：",memberLen)

	err:=pitaya.GroupRemoveMember(context.Background(),r.ID,uid)

	if memberLen == 0{
		fmt.Println("房间没有成员，即将删除组信息：",memberLen)
		pitaya.GroupDelete(context.Background(),r.ID)
	}

	return userInfo,err
}


func (r *Room) Message(ctx context.Context,data *protos.SendMessageToRoomReq) (*protos.RequestRes,error){

	s := pitaya.GetSessionFromCtx(ctx)
	uid:= s.UID()
	r.RW.RLock()
	defer r.RW.RUnlock()
	userInfo ,ok := r.member[uid]
	fmt.Println("userInfo",uid,userInfo,ok)
	if uid == "" || !ok{
		return 	utils.Utils.ReturnTextData("messageRespond", "10003",ctx),nil
	}

	err:=pitaya.GroupBroadcast(
			ctx,
			"chatroom",
			data.RoomId,
			"onMessage",
			utils.Utils.ReturnComplexData("messageNotify",200, map[string]interface{}{
				"username": userInfo.Username,
				"content":data.Content,
			}),
		)

	return 	utils.Utils.ReturnCustomTextData("messageRespond", 200,"消息发送成功",ctx),err

}



func (r *Room) Enter(ctx context.Context,data *protos.EnterRoomReq) (*protos.RequestRes,error){

	s := pitaya.GetSessionFromCtx(ctx)
	uid:= s.UID()
	// 需要检查一下是否进过该房间
	if uid !="" {
		isExists ,err:= pitaya.GroupContainsMember(ctx,r.ID,uid)

		if err ==  constants.ErrGroupNotFound {
			return utils.Utils.ReturnTextData("enterRespond", "10001",ctx),nil
		}

		if isExists == true {
			return utils.Utils.ReturnTextData("enterRespond", "10005",ctx),nil
		}
	}


	//将该用户加入进该房间
	userInfo:= &UserInfo{
		Username: data.Username,
	}
	b,_:=json.Marshal(map[string]string{
		"nickName":data.Username,
		"roomId":r.ID,
		"backendServerId":pitaya.GetServerID(),
	})

	sessionInfo := string(b)
	fmt.Println("同步一下状态")
	pitaya.RPC(ctx,"chatroom.connectorremote.updatelocation",&protos.RPCRes{},&protos.RPCReq{Msg:sessionInfo})
	r.RW.Lock()
	defer r.RW.Unlock()

	r.member[uid] = userInfo
	fmt.Println("通知其他成员")
	// 通知 组里其他人员
	// 如果是后端 那么可以指定前端的serverType 就可以完成推送
	notifyRes:=pitaya.GroupBroadcast(
		ctx,
		"chatroom",
		data.RoomId,"onNewUser",
		utils.Utils.ReturnCustomTextData("enterNotify",200, fmt.Sprintf("用户：%s进入房间",data.Username),ctx),
		)
	fmt.Println(notifyRes)
	// 加入到组
	pitaya.GroupAddMember(ctx,data.RoomId,uid)

	//todo 后端要处理前端断线 清数据

	// 打印一下 房间人数
	count, _ := pitaya.GroupCountMembers(context.Background(), r.ID)
	fmt.Printf("当前房间人数：%d",count)

	return utils.Utils.ReturnComplexData("enterRespond", 200, r),nil

}